#region Debug Preprocessor
#if !DEBUG || !TRACE
    // If not debug then take out all debugging.
    #define CPU_DEBUG_OFF
    #undef CPU_DEBUG_ALL
#endif

// Check if both are defined and raise error.
#if CPU_DEBUG_ALL && CPU_DEBUG_OFF
    #error CPU_DEBUG_ALL and CPU_DEBUG_OFF cannot both be defined
#endif

// Define cpu debug if any of the subsections debuging are turned on.
#if (CPU_MEM_DEBUG || CPU_INT_DEBUG || CPU_STACK_DEBUG || CPU_INS_DEBUG || CPU_TIMING_DEBUG) && !CPU_DEBUG_ALL && !CPU_DEBUG_OFF
    #define CPU_DEBUG
#endif

// Turn on all cpu debug.
#if CPU_DEBUG_ALL
    #define CPU_DEBUG
    #define CPU_MEM_DEBUG
    #define CPU_INT_DEBUG
    #define CPU_INS_DEBUG
    #define CPU_STACK_DEBUG
    #define CPU_TIMING_DEBUG
#endif

// Turn of all cpu debug.
#if CPU_DEBUG_OFF
    #undef CPU_DEBUG
    #undef CPU_MEM_DEBUG
    #undef CPU_INT_DEBUG
    #undef CPU_INS_DEBUG
    #undef CPU_STACK_DEBUG
    #undef CPU_TIMING_DEBUG
#endif


#endregion Debug Preprocessor

using System;
using System.Collections.Generic;
using System.Text;
using Zsa.Emulation.Util;

namespace Zsa.Emulation.Processor
{
    // The execution part of the cpu class.  Execution is one method in one loop.  
    public partial class Cpu6502 
    {
        #region Fields
        /// <summary>
        /// The zero page offset.
        /// </summary>
        //private const int _ZeroPageOffset = 0;

        

        /// <summary>
        /// The carry page value.
        /// </summary>
        private const int _CarryValue = 1;

        private const int _CarrySubstractValue = 0xFE;

        /// <summary>
        /// The sign bit.
        /// </summary>
        private const int _SignedBit = 0x80;
        // Temp address for data.  
        private ushort _MemoryAddress;
        
        #endregion Fields

        /// <summary>
        /// Executes the specified max cycles.
        /// </summary>
        /// <remarks>
        /// <param name="maxCycles">The max cycles.</param>
        /// <param name="cycles">The cycles.</param>
        public int Execute(int maxCycles)
        {
            #region Local Vars

            // The total number of cycles that have been executed.
            int _TotalCycles = 0;
            // The current op code.
            OpCodes _OpCode;
            // Data used for operation.
            ushort _OpDataOne, _OpDataTwo;

            // the size of the instruction.
            byte _InstructionSize = 0;
            // The cycle count.
            byte _CycleCount = 0;

            // Temp buffer for instructions.
            _BufferTemp = new byte[16];
            ///Clear the lcoal vars.
            _MemoryAddress = 0;
            #endregion Local Vars

            // Execute loop.
            while (_TotalCycles < maxCycles)
            {
                #region Interrupt Code
                // Do the dma if there is one.
                if (_Memory.HasDma)
                {
                    _TotalCycles += 512;
                    continue;
                }
                if (_PendingInterrupt != InterruptType.Unknown)
                {
                    // Ignore break if interrupt enabled flag is false.
                    if(true)
                        //((_PendingInterrupt == InterruptType.Break && InterruptsEnabled))
                    {
                        LogInterrupt(_PendingInterrupt, false);
                        // Add 7 cycles.
                        _TotalCycles += 7;

                        // dont push the reset interrupt pc on to stack
                        if (_PendingInterrupt != InterruptType.Reset)
                        {
                            // Write the status, and the pc register to the stack.
                            PushAddress(_RegisterProgramCounter);
                            Push((byte)_RegisterStatus);
                        }
                        else
                        {
                            _RegisterStackPointer = 0xFF;
                        }

                        // Set the current stack address.
                        _RegisterProgramCounter = (ushort)_PendingInterrupt;
                        // Read the interrupt vector.
                        _Memory.Read(_BufferTemp, _RegisterProgramCounter, 2);
                        // Get the address.
                        _RegisterProgramCounter = (ushort)(_BufferTemp[1] << 8 | _BufferTemp[0]);
                        //Set the current interrupt.
                        _CurrentInterrupt = _PendingInterrupt;
                        // Set interrupts enabled to false.
                        InterruptsEnabled = true;
                        // Set the pending interrupt to nothing.
                        _PendingInterrupt = InterruptType.Unknown;
                    }
                    else
                    {
                        LogInterrupt(_PendingInterrupt, true);
                        _PendingInterrupt = InterruptType.Unknown;
                    }

                }
                //else
                //{
                //    if (_CurrentInterrupt != InterruptType.Unknown)
                //    {
                //        _CurrentInterrupt = InterruptType.Unknown;

                //    }
                //}

                #endregion Interrupt

                #region Read Instruction Code
                // Read the current intruction from memory and the data. 1-3 bytes.
                _Memory.Read(_BufferTemp, _RegisterProgramCounter, 3);
                // The current instruction.
                _OpCode = (OpCodes)_BufferTemp[0];
                //Reset the temp data.
                _OpDataOne = 0;
                // The instruction size.
                _InstructionSize = 0;
                // Reset the cycle count.
                _CycleCount = 0;
                // Logs the instruction if cpu debugging is on.
                #if DEBUG && CPU_DEBUG
                LogInstruction(_OpCode);
                #endif 
                #endregion Read Instruction Code

                // This stucks.  Hard to debug.  Should rely on jit inlining instead?
                #region Op Code Switch

                // Switch on the on the op code type.
                switch (_OpCode)
                {
                    #region Stack Instructions - Done

                    #region PHA - Push accumulator on to stack
                    case OpCodes.PHA:
                        _InstructionSize = 1;
                        _CycleCount = 3;
                        //_MemoryAddress = (ushort)(_RegisterStackPointer + _StackOffset);
                        //_Memory.Write(_MemoryAddress, _RegisterAccumulator);
                        //_RegisterStackPointer--;
                        Push(_RegisterAccumulator);
                        break;
                    #endregion PHA - Push accumulator on to stack

                    #region PLA Pull accumulator from stack
                    case OpCodes.PLA:
                        _InstructionSize = 1;
                        _CycleCount = 4;
                        _RegisterAccumulator = Pop();
                        SignedStatusFlag = ((_SignedBit & _RegisterAccumulator) != 0);
                        ZeroStatusFlag = ((_RegisterAccumulator & 0xFF) == 0);
                        //_MemoryAddress = (ushort)(((byte)(_RegisterStackPointer + 1)) + _StackOffset);
                        //_RegisterAccumulator = _Memory.Read(_MemoryAddress);
                        //_RegisterStackPointer++;
                        break;
                    #endregion PLA Pull accumulator from stack

                    #region PHP - Push processor status on to stack
                    case OpCodes.PHP:
                        _InstructionSize = 1;
                        _CycleCount = 3;
                        Push(((byte)_RegisterStatus));
                        //_MemoryAddress = (ushort)(_RegisterStackPointer + _StackOffset);
                        //_Memory.Write(_MemoryAddress, (byte)_RegisterStatus);
                        //_RegisterStackPointer--;
                        break;
                    #endregion PHP - Pull processor status on to stack

                    #region PLP - Pull processor status from stack
                    case OpCodes.PLP:
                        _InstructionSize = 1;
                        _CycleCount = 4;
                        _RegisterStatus = (StatusRegisterFlags)Pop();
                        //_MemoryAddress = (ushort)(((byte)(_RegisterStackPointer + 1)) + _StackOffset);
                        //_RegisterStatus = (StatusRegisterFlags)_Memory.Read(_MemoryAddress);
                        //_RegisterStackPointer++;
                        break;
                    #endregion PLP - Pull processor status from stack
                    #endregion Stack Instructions

                    #region Increment / Decrement Instructions - Done

                    #region DEC - Decrement memory by one
                    case OpCodes.DEC_Z:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;
                                               

                        // Get the zero page address.
                        _MemoryAddress = (ushort)(_BufferTemp[1]);
                        // Read and decrement the data.
                        _OpDataOne = (ushort)(((byte)(_MainMemory[_MemoryAddress] - 1)));
                        //Write back.
                        _MainMemory[_MemoryAddress] = (byte)_OpDataOne;

                        #if DEBUG
                        LogRead((byte)(_OpDataOne + 1));
                        LogWrite(_OpDataOne);
                        #endif

                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) == _SignedBit;
                        break;
                    case OpCodes.DEC_ZX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;
                        // Get the zero page address.
                        _MemoryAddress = (ushort)((byte)(_BufferTemp[1] + _RegisterX));
                        // Read and decrement the data.
                        _OpDataOne = (ushort)(((byte)(_MainMemory[_MemoryAddress] - 1)));
                        //Write back.
                        _MainMemory[_MemoryAddress] = (byte)_OpDataOne;


                        #if DEBUG
                        LogRead((byte)(_OpDataOne + 1));
                        LogWrite(_OpDataOne);
                        #endif

                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) == _SignedBit;
                        break;
                    case OpCodes.DEC_A:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 3;
                        // Get the zero page address.
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);
                        // Read and decrement the data.
                        _OpDataOne = (ushort)((byte)(_Memory.Read(_MemoryAddress) - 1));
                        //Write the data.
                        _Memory.Write(_MemoryAddress, (byte)_OpDataOne);

                        #if DEBUG
                        LogRead((byte)(_OpDataOne + 1));
                        LogWrite(_OpDataOne);
                        #endif

                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) == _SignedBit;
                        break;
                    case OpCodes.DEC_AX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 3;
                        // Get the zero page address.
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterX);
                        // Read and decrement the data.
                        _OpDataOne = (ushort)((byte)(_Memory.Read(_MemoryAddress) - 1));
                        //Write the data.
                        _Memory.Write(_MemoryAddress, (byte)_OpDataOne);

                        #if DEBUG
                        LogRead((byte)(_OpDataOne + 1));
                        LogWrite(_OpDataOne);
                        #endif

                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) == _SignedBit;

                        break;
                    #endregion DEC - Decrement memory by one

                    #region DEX - Decrement index X by one
                    case OpCodes.DEX:
                        _CycleCount = 2;
                        _InstructionSize = 1;
                        _RegisterX--;
                        ZeroStatusFlag = _RegisterX == 0;
                        SignedStatusFlag = (_RegisterX & _SignedBit) ==_SignedBit;
                        break;
                    #endregion DEX - Decrement index X by one

                    #region DEY - Decrement index Y by one
                    case OpCodes.DEY:
                        _CycleCount = 2;
                        _InstructionSize = 1;
                        _RegisterY--;
                        ZeroStatusFlag = _RegisterY == 0;
                        SignedStatusFlag = (_RegisterY & _SignedBit) ==_SignedBit;
                        break;
                    #endregion DEY - Decrement index Y by one

                    #region INC - Increment memory by one
                    case OpCodes.INC_A:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 3;
                        // Get the absolute address.
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);
                        // Read and increment the data.
                        _OpDataOne = (ushort)((byte)(_Memory.Read(_MemoryAddress) + 1));
                        //Write the data.
                        _Memory.Write(_MemoryAddress, (byte)_OpDataOne);

                        #if DEBUG
                        LogRead((byte)(_OpDataOne - 1));
                        LogWrite(_OpDataOne);
                        #endif

                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) == _SignedBit;
                        break;
                    case OpCodes.INC_AX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 3;
                        // Get the zero page address.
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterX);
                        // Read and increment the data.
                        _OpDataOne = (ushort)((byte)(_Memory.Read(_MemoryAddress) + 1));
                        //Write the data.
                        _Memory.Write(_MemoryAddress, (byte)_OpDataOne);

                        #if DEBUG
                        LogRead((byte)(_OpDataOne - 1));
                        LogWrite(_OpDataOne);
                        #endif

                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) == _SignedBit;
                        break;
                    case OpCodes.INC_Z:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;

                        // Get the zero page address.
                        _MemoryAddress = (ushort)(_BufferTemp[1]);
                        // Read and decrement the data.
                        _OpDataOne = (ushort)(((byte)(_MainMemory[_MemoryAddress] + 1)));
                        //Write back.
                        _MainMemory[_MemoryAddress] = (byte)_OpDataOne;

                        #if DEBUG
                        LogRead((byte)(_OpDataOne - 1));
                        LogWrite(_OpDataOne);
                        #endif

                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) == _SignedBit;
                        break;
                    case OpCodes.INC_ZX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;

                        // Get the zero page address.
                        _MemoryAddress = (ushort)((byte)(_BufferTemp[1] + _RegisterX));
                        // Read and decrement the data.
                        _OpDataOne = (ushort)(((byte)(_MainMemory[_MemoryAddress] + 1)));
                        //Write back.
                        _MainMemory[_MemoryAddress] = (byte)_OpDataOne;


                        #if DEBUG
                        LogRead((byte)(_OpDataOne - 1));
                        LogWrite(_OpDataOne);
                        #endif

                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) ==_SignedBit;
                        break;
                    #endregion INC - Increment memory by one

                    #region INX - Increment Index X by one
                    case OpCodes.INX:
                        _CycleCount = 2;
                        _InstructionSize = 1;
                        _RegisterX++;
                        ZeroStatusFlag = _RegisterX == 0;
                        SignedStatusFlag = (_RegisterX & _SignedBit) ==_SignedBit;
                        break;
                    #endregion INX - Increment Index X by one

                    #region INY - Increment Index Y by one
                    case OpCodes.INY:
                        _InstructionSize = 1;
                        _CycleCount = 2;
                        _RegisterY++;
                        ZeroStatusFlag = _RegisterY == 0;
                        SignedStatusFlag = (_RegisterY & _SignedBit) ==_SignedBit;
                        break;
                    #endregion INY - Increment Index Y by one

                    #endregion Increment / Decrement Instructions

                    #region Status Instructions - Done

                    #region SEC - Set carry flag
                    case OpCodes.SEC:
                        // Set the cycle size and instruction counts.
                        _CycleCount = 2;
                        _InstructionSize = 1;
                        CarryFlag = true;
                        break;
                    #endregion SEC - Set carry flag

                    #region SED - Set decimal mode
                    case OpCodes.SED:
                        // Set the cycle size and instruction counts.
                        _CycleCount = 2;
                        _InstructionSize = 1;
                        DecimalFlag = true;
                        break;
                    #endregion SED - Set decimal mode

                    #region SEI - Set interrupt disable status
                    case OpCodes.SEI:
                        // Set the cycle size and instruction counts.
                        _CycleCount = 2;
                        _InstructionSize = 1;
                        InterruptsEnabled = true;
                        break;
                    #endregion SEI - Set interrupt disable status

                    #region CLC - Clear Carry Flag
                    case OpCodes.CLC:
                        // Set the cycle size and instruction counts.
                        _CycleCount = 2;
                        _InstructionSize = 1;
                        CarryFlag = false;
                        break;
                    #endregion CLC - Clear Carry Flag

                    #region CLD - Clear Decimal Flag
                    case OpCodes.CLD:
                        // Set the cycle size and instruction counts.
                        _CycleCount = 2;
                        _InstructionSize = 1;
                        DecimalFlag = false;
                        break;
                    #endregion CLD - Clear Decimal Flag

                    #region CLI - Clear Interrupt  Flag
                    case OpCodes.CLI:
                        // Set the cycle size and instruction counts.
                        _CycleCount = 2;
                        _InstructionSize = 1;
                        InterruptsEnabled = false;
                        break;
                    #endregion CLI - Clear Overflow  Flag

                    #region CLV - Clear Overflow  Flag
                    case OpCodes.CLV:
                        // Set the cycle size and instruction counts.
                        _CycleCount = 2;
                        _InstructionSize = 1;
                        OverFlowFlag = false;
                        break;
                    #endregion CLV - Clear Overflow  Flag

                    #endregion Status Instructions

                    #region Jumps / Calls - Done

                    #region JMP - Jump to new location
                    case OpCodes.JMP_A:
                        _CycleCount = 2;
                        _InstructionSize = 3;
                        // Get the jump address.
                        _MemoryAddress = (ushort)(_BufferTemp[1] | _BufferTemp[2] << 8);
                        // Set the pc to be the new address minus 3
                        _RegisterProgramCounter = (ushort)(_MemoryAddress - 3);
                        break;
                    case OpCodes.JMP_I:
                        _CycleCount = 2;
                        _InstructionSize = 3;
                        // Get the jump address.
                        _MemoryAddress = (ushort)(_BufferTemp[1] |(_BufferTemp[2] << 8));
                            

                        if (_BufferTemp[1] == 0xFF)
                        {
                            _OpDataOne = (ushort)(_Memory.Read(_MemoryAddress));

                            _MemoryAddress = (ushort)(_BufferTemp[2] << 8);
                            _OpDataOne |= (ushort)(_Memory.Read(_MemoryAddress) << 8);
                            //(_BufferTemp[2] == 0xFF ? 0 : (_BufferTemp[2] << 8)));
                        }
                        else
                        {
                            // Read the new address.
                            _OpDataOne = (ushort)(_Memory.Read(_MemoryAddress) | (_Memory.Read(_MemoryAddress + 1) << 8));
                        }
                        // Set the pc to be the new address minus 3
                        _RegisterProgramCounter = (ushort)(_OpDataOne - 3);
                        break;
                    #endregion JMP - Jump to new location

                    #region JSR - Jump to new location saving return address
                    case OpCodes.JSR:
                        _CycleCount = 2;
                        _InstructionSize = 3;
                        // Push the address on to the stack.
                        PushAddress((ushort)(_RegisterProgramCounter + 2));
                        // Get the jump address.
                        _MemoryAddress = (ushort)(_BufferTemp[1] | _BufferTemp[2] << 8);
                        // Set the pc to be the new address minus 3.  Extra 3 for instruction size.
                        _RegisterProgramCounter = (ushort)(_MemoryAddress - 3);
                        break;
                    #endregion JSR - Jump to new location saving return address

                    #region RTS - Return from subroutine
                    case OpCodes.RTS:
                        
                        _CycleCount = 1;
                        _InstructionSize = 1;
                        // Pop the address off the stack.
                        PopAddress();

                        break;
                    #endregion RTS - Return from subroutine

                    #region RTI - Return from Iterrupt
                    case OpCodes.RTI:
                        _CycleCount = 1;
                        _InstructionSize = 1;
                        //Pop the register status from the stack.
                        _RegisterStatus = (StatusRegisterFlags)Pop();
                        // Pop the program counter off the stack.
                        PopAddress();
                        _RegisterProgramCounter--;
                        break;
                    #endregion RTI - Return from Iterrupt

                    #endregion Jumps / Calls - Done

                    #region Branch Instructions - Done

                    #region BCC - Branch On Carry Clear
                    case OpCodes.BCC:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 2;
                        // Check if the overflow flag is set.  If so then branch.
                        if (!CarryFlag)
                        {
                            _RegisterProgramCounter = (ushort)
                                (((int)_RegisterProgramCounter) + ((sbyte)_BufferTemp[1]));
                        }
                        break;

                    #endregion BCC - Branch On Carry Clear

                    #region BCS - Branch On Carry Set
                    case OpCodes.BCS:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 2;
                        // Check if the overflow flag is set.  If so then branch.
                        if (CarryFlag)
                        {
                            _RegisterProgramCounter = (ushort)
                                (((int)_RegisterProgramCounter) + ((sbyte)_BufferTemp[1]));
                        }
                        break;

                    #endregion BCS

                    #region BEQ - Branch On Result Zero
                    case OpCodes.BEQ:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 2;
                        // Check if the overflow flag is set.  If so then branch.
                        if (ZeroStatusFlag)
                        {
                            _RegisterProgramCounter = (ushort)
                                (((int)_RegisterProgramCounter) + ((sbyte)_BufferTemp[1]));
                        }
                        break;

                    #endregion BCS

                    #region BNE - Branch On Result Not Zero
                    case OpCodes.BNE:
                        // Set the cycles and instruction size.
                        _CycleCount = 2;
                        _InstructionSize = 2;
                        if (!ZeroStatusFlag)
                        {
                            _RegisterProgramCounter = (ushort)
                                (((int)_RegisterProgramCounter) + ((sbyte)_BufferTemp[1]));
                            break;
                        }
                        else
                        {
                            break;
                        }

                    #endregion BNE - Branch On Result Not Zero

                    #region BVC - Branch on overflow clear
                    case OpCodes.BVC:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 2;
                        // Check if the overflow flag is set.  If so then branch.
                        if (!OverFlowFlag)
                        {
                            _RegisterProgramCounter = (ushort)
                                (((int)_RegisterProgramCounter) + ((sbyte)_BufferTemp[1]));
                        }
                        break;
                    #endregion BVC - Branch on overflow clear

                    #region BVS - Branch on overflow set
                    case OpCodes.BVS:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 2;
                        // Check if the overflow flag is set.  If so then branch.
                        if (OverFlowFlag)
                        {
                            _RegisterProgramCounter = (ushort)
                                (((int)_RegisterProgramCounter) + ((sbyte)_BufferTemp[1]));
                        }
                        break;

                    #endregion BVS - Branch on overflow set

                    #region BMI - Branch On Result Minus
                    case OpCodes.BMI:
                        // Set the cycles and instruction size.
                        _CycleCount = 2;
                        _InstructionSize = 2;
                        if (SignedStatusFlag)
                        {
                            _RegisterProgramCounter = (ushort)
                                (((int)_RegisterProgramCounter) + ((sbyte)_BufferTemp[1]));
                        }
                        break;

                    #endregion BMI

                    #region BPL - Branch On Result Plus
                    case OpCodes.BPL:
                        // Set the cycles and instruction size.
                        _CycleCount = 2;
                        _InstructionSize = 2;
                        if (!SignedStatusFlag)
                        {
                            _RegisterProgramCounter = (ushort)
                                (((int)_RegisterProgramCounter) + ((sbyte)_BufferTemp[1]));
                        }
                        break;
                    #endregion BPL

                    #endregion Branch Instructions

                    #region Transfer Instructions - Done

                    #region TAX - Transfer accumulator to index X
                    case OpCodes.TAX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 1;
                        _CycleCount = 2;
                        _RegisterX = _RegisterAccumulator;

                        ZeroStatusFlag = _RegisterX == 0;
                        SignedStatusFlag = (_RegisterX & _SignedBit) != 0;
                        break;
                    #endregion TAX - Transfer accumulator to indexX

                    #region TAY - Transfer accumulator to index Y
                    case OpCodes.TAY:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 1;
                        _CycleCount = 2;
                        _RegisterY = _RegisterAccumulator;


                        ZeroStatusFlag = _RegisterY == 0;
                        SignedStatusFlag = (_RegisterY & _SignedBit) != 0;
                        break;
                    #endregion TAY - Transfer accumulator to index Y

                    #region TXA - Transfer index X to accumulator
                    case OpCodes.TXA:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 1;
                        _CycleCount = 2;
                        _RegisterAccumulator = _RegisterX;

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;
                    #endregion TXA - Transfer index X to accumulator

                    #region TYA - Transfer index Y to accumulator
                    case OpCodes.TYA:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 1;
                        _CycleCount = 2;
                        _RegisterAccumulator = _RegisterY;

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;
                    #endregion TYA - Transfer index Y to accumulator

                    #region TXS - Transfer index X to stack pointer
                    case OpCodes.TXS:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 1;
                        _CycleCount = 2;
                        _RegisterStackPointer = _RegisterX;
                        break;
                    #endregion TXS - Transfer index X to stack pointer

                    #region TSX - Transfer stack pointer to index X
                    case OpCodes.TSX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 1;
                        _CycleCount = 2;
                        _RegisterX = _RegisterStackPointer;

                        ZeroStatusFlag = _RegisterX == 0;
                        SignedStatusFlag = (_RegisterX & _SignedBit) != 0;
                        break;
                    #endregion TSX - Transfer stack pointer to index X

                    #endregion Transfer Instructions

                    #region Load Instructions - Done

                    #region LDA - Load accumulator with memory
                    case OpCodes.LDA_Z:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;
                        // Get the zero page address.
                        _MemoryAddress = (ushort)((_BufferTemp[1]));
                        // Read the value from memory.
                        _RegisterAccumulator = _MainMemory[_BufferTemp[1]];

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = ((_RegisterAccumulator & _SignedBit) == _SignedBit);
                       // LogCpuMemoryReadWrite(true, _BufferTemp[1], _RegisterAccumulator);
                        break;
                    case OpCodes.LDA_ZX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;
                        // Get the zero page address.
                        _RegisterAccumulator = _MainMemory[((byte)(_BufferTemp[1] + _RegisterX))];

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = ((_RegisterAccumulator & _SignedBit) == _SignedBit);
                        //LogCpuMemoryReadWrite(true, ((byte)(_BufferTemp[1] + _RegisterX)), _RegisterAccumulator);
                        break;
                    case OpCodes.LDA:
                        _InstructionSize = 2;
                        _CycleCount = 2;
                        _RegisterAccumulator = _BufferTemp[1];

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = ((_RegisterAccumulator & _SignedBit) ==_SignedBit);
                        break;
                    case OpCodes.LDA_A:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);
                        _RegisterAccumulator = _Memory.Read(_MemoryAddress);

                        LogRead(_RegisterAccumulator);

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = ((_RegisterAccumulator & _SignedBit) == _SignedBit);
                       // LogCpuMemoryReadWrite(true, _MemoryAddress, _RegisterAccumulator);
                        break;
                    case OpCodes.LDA_AY:
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterY);
                        _RegisterAccumulator = _Memory.Read(_MemoryAddress);

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = ((_RegisterAccumulator & _SignedBit) == _SignedBit);
                        //LogCpuMemoryReadWrite(true, _MemoryAddress, _RegisterAccumulator);
                        break;
                    case OpCodes.LDA_AX:
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterX);
                        _RegisterAccumulator = _Memory.Read(_MemoryAddress);

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = ((_RegisterAccumulator & _SignedBit) == _SignedBit);
                      //  LogCpuMemoryReadWrite(true, _MemoryAddress, _RegisterAccumulator);
                        break;
                    case OpCodes.LDA_IX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 6;

                        // Read the indirectX address
                        ReadAddressIndirectX();

                        // Write the value to memory.
                        _RegisterAccumulator = _Memory.Read(_MemoryAddress);

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = ((_RegisterAccumulator & _SignedBit) ==_SignedBit);
                       // LogCpuMemoryReadWrite(true, _MemoryAddress, _RegisterAccumulator);
                        break;
                    case OpCodes.LDA_IY:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 6;

                        // Get the indirect y address.
                        ReadAddressIndirectY();

                        // Read the value from memory.
                        _RegisterAccumulator = _Memory.Read(_MemoryAddress);

                        // Set the status flags.
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = ((_RegisterAccumulator & _SignedBit) == _SignedBit);
                      //  LogCpuMemoryReadWrite(true, _MemoryAddress, _RegisterAccumulator);

                        break;

                    #endregion LDA - Load accumulator with memory

                    #region LDX - Load index X with memory
                    case OpCodes.LDX:
                        // Set cycles and instruction counts.
                        _InstructionSize = 2;
                        _CycleCount = 2;
                        _RegisterX = _BufferTemp[1];

                        ZeroStatusFlag = _RegisterX == 0;
                        SignedStatusFlag = ((_RegisterX & _SignedBit) == _SignedBit);
                        break;
                    case OpCodes.LDX_A:
                        // Set the cycle size and instruction counts.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the memory address.
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]));
                        // Write the accumatlor to memory.
                        _RegisterX = _Memory.Read(_MemoryAddress);

                        ZeroStatusFlag = _RegisterX == 0;
                        SignedStatusFlag = ((_RegisterX & _SignedBit) == _SignedBit);
                        break;
                    case OpCodes.LDX_AY:
                        // Set the cycle size and instruction counts.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the memory address.
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterY);
                        // Write the accumatlor to memory.
                        _RegisterX = _Memory.Read(_MemoryAddress);

                        ZeroStatusFlag = _RegisterX == 0;
                        SignedStatusFlag = ((_RegisterX & _SignedBit) == _SignedBit);
                        break;
                    case OpCodes.LDX_Z:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;
                        // Read the data.
                        _RegisterX = _MainMemory[_BufferTemp[1]];

                        ZeroStatusFlag = _RegisterX == 0;
                        SignedStatusFlag = ((_RegisterX & _SignedBit) == _SignedBit);
                        break;
                    case OpCodes.LDX_ZY:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;
                        // Read the data.
                        _RegisterX = _MainMemory[((byte)(_BufferTemp[1] + _RegisterY))];

                        ZeroStatusFlag = _RegisterX == 0;
                        SignedStatusFlag = ((_RegisterX & _SignedBit) == _SignedBit);
                        break;
                    #endregion LDX - Load index X with memory

                    #region LDY Load index Y with memory
                    case OpCodes.LDY:
                        // Set cycles and instruction counts.
                        _InstructionSize = 2;
                        _CycleCount = 2;
                        _RegisterY = _BufferTemp[1];

                        ZeroStatusFlag = _RegisterY == 0;
                        SignedStatusFlag = ((_RegisterY & _SignedBit) == _SignedBit);
                        break;
                    case OpCodes.LDY_A:
                        // Set the cycle size and instruction counts.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the memory address.
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]));
                        // Write the accumatlor to memory.
                        _RegisterY = _Memory.Read(_MemoryAddress);

                        ZeroStatusFlag = _RegisterY == 0;
                        SignedStatusFlag = ((_RegisterY & _SignedBit) == _SignedBit);
                        break;
                    case OpCodes.LDY_AX:
                        // Set the cycle size and instruction counts.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the memory address.
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterX);
                        // Write the accumatlor to memory.
                        _RegisterY = _Memory.Read(_MemoryAddress);

                        ZeroStatusFlag = _RegisterY == 0;
                        SignedStatusFlag = ((_RegisterY & _SignedBit) == _SignedBit);
                        break;
                    case OpCodes.LDY_Z:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;
                        // Read the data.
                        _RegisterY = _MainMemory[_BufferTemp[1]];

                        ZeroStatusFlag = _RegisterY == 0;
                        SignedStatusFlag = ((_RegisterY & _SignedBit) == _SignedBit);
                        break;
                    case OpCodes.LDY_ZX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;
                        // Read the data.
                        _RegisterY = _MainMemory[((byte)(_BufferTemp[1] + _RegisterX))];

                        ZeroStatusFlag = _RegisterY == 0;
                        SignedStatusFlag = ((_RegisterY & _SignedBit) == _SignedBit);
                        break;
                    #endregion LDY Load index Y with memory

                    #endregion Load Instructions

                    #region Store Instructions - Done

                    #region STA - Store accumulator in memory
                    case OpCodes.STA_Z:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;
                        // Get the zero page address.
                        _MemoryAddress = ((ushort)(_BufferTemp[1]));
                        // Write the data.
                        _Memory.Write(_MemoryAddress, _RegisterAccumulator);
                       // LogCpuMemoryReadWrite(false, _MemoryAddress, _RegisterAccumulator);
                        break;
                    case OpCodes.STA_ZX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;
                        // Get the zero page address.
                        _MemoryAddress = (ushort)((byte)(_BufferTemp[1] + _RegisterX));
                        // Write the data.
                        _Memory.Write(_MemoryAddress, _RegisterAccumulator);
                       // LogCpuMemoryReadWrite(false, _MemoryAddress, _RegisterAccumulator);
                        break;
                    case OpCodes.STA_A:
                        // Set the cycle size and instruction counts.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the memory address.
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);
                        // Write the accumatlor to memory.
                        _Memory.Write(_MemoryAddress, _RegisterAccumulator);
                       // LogCpuMemoryReadWrite(false, _MemoryAddress, _RegisterAccumulator);
                        break;
                    case OpCodes.STA_AX:
                        // Set the cycle size and instruction counts.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the memory address.
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterX);
                        // Write the accumatlor to memory.
                        _Memory.Write(_MemoryAddress, _RegisterAccumulator);
                       // LogCpuMemoryReadWrite(false, _MemoryAddress, _RegisterAccumulator);
                        break;
                    case OpCodes.STA_AY:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the address.  
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterY);
                        // Read the byte from memory.
                        _Memory.Write(_MemoryAddress, _RegisterAccumulator);
                      //  LogCpuMemoryReadWrite(false, _MemoryAddress, _RegisterAccumulator);
                        break;
                    case OpCodes.STA_IX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 6;

                        // Read the indirectX address
                        ReadAddressIndirectX();

                        // Write the value to memory.
                        _Memory.Write(_MemoryAddress, _RegisterAccumulator);
                        break;
                    case OpCodes.STA_IY:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 6;

                        // Get the indirect y address.
                        ReadAddressIndirectY();

                        // Write the value to memory.
                        _Memory.Write(_MemoryAddress, _RegisterAccumulator);
                        break;

                    #endregion STA - Store accumulator in memory

                    #region STX - Store index X in memory
                    // Absolute
                    case OpCodes.STX_A:
                        // Set the cycle size and instruction counts.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the memory address.
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);
                        // Write the accumatlor to memory.
                        _Memory.Write(_MemoryAddress, _RegisterX);
                      //  LogCpuMemoryReadWrite(false, _MemoryAddress, _RegisterX);
                        break;
                    case OpCodes.STX_Z:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;
                        // Get the zero page address.
                        _MemoryAddress = ((ushort)(_BufferTemp[1]));
                        // Write the data.
                        _Memory.Write(_MemoryAddress, _RegisterX);
                       // LogCpuMemoryReadWrite(false, _MemoryAddress, _RegisterX);
                        break;
                    case OpCodes.STX_ZY:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;
                        // Get the zero page address.
                        _MemoryAddress = (ushort)((byte)(_BufferTemp[1] + _RegisterY));
                        // Write the data.
                        _Memory.Write(_MemoryAddress, _RegisterX);
                       // LogCpuMemoryReadWrite(false, _MemoryAddress, _RegisterX);
                        break;
                    #endregion STX - Store index X in memory

                    #region STY - Store index Y in memory
                    // Absolute
                    case OpCodes.STY_A:
                        // Set the cycle size and instruction counts.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the memory address.
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);
                        // Write the accumatlor to memory.
                        _Memory.Write(_MemoryAddress, _RegisterY);
                      //  LogCpuMemoryReadWrite(false, _MemoryAddress, _RegisterY);
                        break;
                    case OpCodes.STY_Z:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;

                        // Get the zero page address.
                        _MemoryAddress = ((ushort)(_BufferTemp[1]));
                        // Write the data.
                        _Memory.Write(_MemoryAddress, _RegisterY);
                        //   LogCpuMemoryReadWrite(false, _MemoryAddress, _RegisterY);



                        //// Write the data.
                        //_MainMemory[_BufferTemp[1]] = _RegisterY;
                        
                        //// Debug
                        //#if CPU_MEM_DEBUG
                        //_MemoryAddress = ((ushort)(_BufferTemp[1]));
                        //LogWrite(_RegisterY);
                        //#endif

                        break;
                    case OpCodes.STY_ZX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;


                        _MemoryAddress = (ushort)((byte)(_BufferTemp[1] + _RegisterX));
                        // Write the data.
                        _Memory.Write(_MemoryAddress, _RegisterY);
                      //  LogCpuMemoryReadWrite(false, _MemoryAddress, _RegisterY);


                    
                        //// Write the data.
                        //_MainMemory[((byte)(_BufferTemp[1] + _RegisterX))]=_RegisterY;
                        
                        //// Debug
                        //#if CPU_MEM_DEBUG
                        //_MemoryAddress = (ushort)((byte)(_BufferTemp[1] + _RegisterX));
                        //LogWrite(_RegisterY);
                        //#endif
                        
                        break;
                    #endregion STY - Store index Y in memory

                    #endregion Store Instructions

                    #region Biswise Instructions - Done

                    #region AND - Bitwise AND
                    case OpCodes.AND:
                        // Set the instruction size and cycle count.
                        _CycleCount = 2;
                        _InstructionSize = 2;
                        // And the value to accumulator.
                        _RegisterAccumulator = (byte)(_RegisterAccumulator & ((byte)(_BufferTemp[1])));
                        //set the status flags.
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;


                        break;

                    case OpCodes.AND_Z:

                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 2;
                        // Get the zero page address.
                        _MemoryAddress = (ushort)(_BufferTemp[1]);
                        // Read the data.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        // And the value to accumulator.
                        _RegisterAccumulator = (byte)(_RegisterAccumulator & ((byte)(_OpDataOne)));
                        //set the status flags.
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;

                    case OpCodes.AND_ZX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;
                        // Get the zero page address.
                        _MemoryAddress = (ushort)((byte)(_BufferTemp[1] + _RegisterX));
                        // Read the data.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        // And the value to accumulator.
                        _RegisterAccumulator = (byte)(_RegisterAccumulator & ((byte)(_OpDataOne)));
                        //set the status flags.
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;

                    // Absolute.  The address should be the next 2 bytes 
                    case OpCodes.AND_A:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the address.  
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);
                        // Read the byte from memory.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        // And the value to accumulator.
                        _RegisterAccumulator = (byte)(_RegisterAccumulator & ((byte)(_OpDataOne)));
                        //set the status flags.
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;

                    // Absolute.  The address should be the next 2 bytes.  Add x.
                    case OpCodes.AND_AX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the address.  
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterX);
                        // Read the byte from memory.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        // And the value to accumulator.
                        _RegisterAccumulator = (byte)(_RegisterAccumulator & ((byte)(_OpDataOne)));
                        //set the status flags.
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;

                    // Absolute.  The address should be the next 2 bytes.  Add y.
                    case OpCodes.AND_AY:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the address.  
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterY);
                        // Read the byte from memory.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        // And the value to accumulator.
                        _RegisterAccumulator = (byte)(_RegisterAccumulator & ((byte)(_OpDataOne)));
                        //set the status flags.
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;


                    case OpCodes.AND_IX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;

                        // Read the indirectX address
                        ReadAddressIndirectX();

                        // Read the op data.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        // And the value to accumulator.
                        _RegisterAccumulator = (byte)(_RegisterAccumulator & ((byte)(_OpDataOne)));
                        //set the status flags.
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;

                    case OpCodes.AND_IY:

                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;

                        // Get the indirect y address.
                        ReadAddressIndirectY();

                        // Read the op data.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        // And the value to accumulator.
                        _RegisterAccumulator = (byte)(_RegisterAccumulator & ((byte)(_OpDataOne)));
                        //set the status flags.
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;



                    #endregion AND

                    #region ASL - Bitwise Left Shift

                    case OpCodes.ASL_A:
                        _CycleCount = 2;
                        _InstructionSize = 3;
                        // Get the address.  
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);
                        // Read the byte from memory.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);


                        //Shift the value.
                        _OpDataOne <<= 1;
                        // Write the value back to memory.
                        _Memory.Write(_MemoryAddress, (byte)(0xFF & _OpDataOne));

                        // Set the flags.
                        CarryFlag = (_OpDataOne & 0x0100) != 0;
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) != 0;
                        break;


                    case OpCodes.ASL_ACC:
                        _CycleCount = 2;
                        _InstructionSize = 1;

                        // Set the value.
                        _OpDataOne = (ushort)(_RegisterAccumulator);

                        //Shift the value.
                        _OpDataOne <<= 1;
                        // Set the accumulator
                        _RegisterAccumulator = (byte)(_OpDataOne & 0xFF);

                        // Set the flags.
                        CarryFlag = (_OpDataOne & 0x0100) != 0;
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) != 0;

                        break;

                    case OpCodes.ASL_AX:
                        _CycleCount = 2;
                        _InstructionSize = 2;

                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterX);
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        //Shift the value.
                        _OpDataOne <<= 1;
                        // Write the value back to memory.
                        _Memory.Write(_MemoryAddress, (byte)(0xFF & _OpDataOne));

                        // Set the flags.
                        CarryFlag = (_OpDataOne & 0x0100) != 0;
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) != 0;
                        break;


                    case OpCodes.ASL_Z:
                        _CycleCount = 2;
                        _InstructionSize = 2;

                        _MemoryAddress = (ushort)(_BufferTemp[1]);
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        //Shift the value.
                        _OpDataOne <<= 1;
                        // Write the value back to memory.
                        _Memory.Write(_MemoryAddress, (byte)(0xFF & _OpDataOne));

                        // Set the flags.
                        CarryFlag = (_OpDataOne & 0x0100) != 0;
                        ZeroStatusFlag = (_OpDataOne&0xFF) == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) != 0;
                        break;

                    case OpCodes.ASL_ZX:
                        _CycleCount = 2;
                        _InstructionSize = 2;

                        _MemoryAddress = (ushort)((byte)(_BufferTemp[1] + _RegisterX));
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        //Shift the value.
                        _OpDataOne <<= 1;
                        // Write the value back to memory.
                        _Memory.Write(_MemoryAddress, (byte)(0xFF & _OpDataOne));

                        // Set the flags.
                        CarryFlag = (_OpDataOne & 0x0100) != 0;
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) != 0;
                        break;
                    #endregion ASL

                    #region EOR - "Exclusive-Or" memory with accumulator

                    case OpCodes.EOR:
                        // Set the instruction size and cycle count.
                        _CycleCount = 2;
                        _InstructionSize = 2;
                        // And the value with the accumulator
                        _RegisterAccumulator = (byte)(_RegisterAccumulator ^ _BufferTemp[1]);
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;
                    case OpCodes.EOR_Z:
                        _CycleCount = 2;
                        _InstructionSize = 2;

                        _MemoryAddress = (ushort)(_BufferTemp[1]);
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);
                        _RegisterAccumulator = (byte)(_RegisterAccumulator ^ (byte)_OpDataOne);
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;
                    case OpCodes.EOR_ZX:
                        _CycleCount = 2;
                        _InstructionSize = 2;

                        _MemoryAddress = (ushort)((byte)(_BufferTemp[1] + _RegisterX));
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);
                        _RegisterAccumulator = (byte)(_RegisterAccumulator ^ (byte)_OpDataOne);
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;


                    case OpCodes.EOR_A:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);

                        _OpDataOne = _Memory.Read(_MemoryAddress);
                        _RegisterAccumulator = (byte)(_RegisterAccumulator ^ (byte)_OpDataOne);

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;

                        break;

                    case OpCodes.EOR_AX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterX);

                        _OpDataOne = _Memory.Read(_MemoryAddress);
                        _RegisterAccumulator = (byte)(_RegisterAccumulator ^ (byte)_OpDataOne);

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;

                        break;
                    case OpCodes.EOR_AY:
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterY);


                        _OpDataOne = _Memory.Read(_MemoryAddress);
                        _RegisterAccumulator = (byte)(_RegisterAccumulator ^ (byte)_OpDataOne);

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;
                    case OpCodes.EOR_IX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 6;

                        // Read the indirectX address
                        ReadAddressIndirectX();

                        // Write the value to memory.
                        _OpDataOne = _Memory.Read(_MemoryAddress);
                        _RegisterAccumulator = (byte)(_RegisterAccumulator ^ (byte)_OpDataOne);

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;
                    case OpCodes.EOR_IY:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 6;

                        // Get the indirect y address.
                        ReadAddressIndirectY();

                        // Read the value from memory.
                        _OpDataOne = _Memory.Read(_MemoryAddress);
                        _RegisterAccumulator = (byte)(_RegisterAccumulator ^ (byte)_OpDataOne);

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;

                    #endregion EOR - "Exclusive-Or" memory with accumulator

                    #region ORA - "OR" memory with accumulator
                    case OpCodes.ORA:
                        // Set the instruction size and cycle count.
                        _CycleCount = 2;
                        _InstructionSize = 2;
                        // And the value with the accumulator
                        _RegisterAccumulator |= _BufferTemp[1];

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;
                    case OpCodes.ORA_Z:
                        _CycleCount = 2;
                        _InstructionSize = 2;

                        _MemoryAddress = (ushort)(_BufferTemp[1]);
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);
                        _RegisterAccumulator |= (byte)_OpDataOne;
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;
                    case OpCodes.ORA_ZX:
                        _CycleCount = 2;
                        _InstructionSize = 2;

                        _MemoryAddress = (ushort)((byte)(_BufferTemp[1] + _RegisterX));
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);
                        _RegisterAccumulator |= (byte)_OpDataOne;

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;


                    case OpCodes.ORA_A:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);
                        _OpDataOne = _Memory.Read(_MemoryAddress);
                        _RegisterAccumulator |= (byte)_OpDataOne;

                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;

                        break;
                    case OpCodes.ORA_AX:
                        _InstructionSize = 3;
                        _CycleCount = 4;

                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterX);
                        _OpDataOne = _Memory.Read(_MemoryAddress);


                        _RegisterAccumulator |= (byte)_OpDataOne;
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;
                    case OpCodes.ORA_AY:
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterY);
                        _OpDataOne = _Memory.Read(_MemoryAddress);
                        _RegisterAccumulator |= (byte)_OpDataOne;
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;
                    case OpCodes.ORA_IX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 6;

                        // Read the indirectX address
                        ReadAddressIndirectX();
                        
                        // Write the value to memory.
                        _OpDataOne = _Memory.Read(_MemoryAddress);
                        _RegisterAccumulator |= (byte)_OpDataOne;
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;
                    case OpCodes.ORA_IY:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 6;

                        // Get the indirect y address.
                        ReadAddressIndirectY();

                        // Read the value from memory.
                        _OpDataOne = _Memory.Read(_MemoryAddress);
                        _RegisterAccumulator |= (byte)_OpDataOne;
                        ZeroStatusFlag = _RegisterAccumulator == 0;
                        SignedStatusFlag = (_RegisterAccumulator & _SignedBit) != 0;
                        break;
                    #endregion ORA - "OR" memory with accumulator

                    #region LSR - Shift right one bit (memory or accumulator)
                    case OpCodes.LSR_A:
                        _InstructionSize = 3;
                        _CycleCount = 4;

                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]));
                        _OpDataOne = _Memory.Read(_MemoryAddress);

                        // Set carry if bit 0 is set.
                        CarryFlag = (_OpDataOne & 1) != 0;
                        // Right shift one.
                        _OpDataOne >>= 1;
                        // Write to memory.
                        _Memory.Write(_MemoryAddress, (byte)_OpDataOne);
                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = false;
                        break;
                    case OpCodes.LSR_ACC:
                        _InstructionSize = 1;
                        _CycleCount = 2;

                        // Set accumalator to temp var.
                        _OpDataOne = _RegisterAccumulator;
                        // Set carry if bit 0 is set.
                        CarryFlag = (_OpDataOne & 1) != 0;
                        // Right shift one.
                        _OpDataOne >>= 1;
                        // Write to memory.
                        _RegisterAccumulator = (byte)_OpDataOne;
                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = false;
                        break;
                    case OpCodes.LSR_AX:
                        _InstructionSize = 3;
                        _CycleCount = 4;

                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterX);
                        _OpDataOne = _Memory.Read(_MemoryAddress);


                        // Set carry if bit 0 is set.
                        CarryFlag = (_OpDataOne & 1) != 0;
                        // Right shift one.
                        _OpDataOne >>= 1;
                        // Write to memory.
                        _Memory.Write(_MemoryAddress, (byte)_OpDataOne);
                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = false;
                        break;
                    case OpCodes.LSR_Z:
                        _InstructionSize = 2;
                        _CycleCount = 4;

                        _MemoryAddress = (ushort)(_BufferTemp[1]);
                        _OpDataOne = _Memory.Read(_MemoryAddress);


                        // Set carry if bit 0 is set.
                        CarryFlag = (_OpDataOne & 1) != 0;
                        // Right shift one.
                        _OpDataOne >>= 1;
                        // Write to memory.
                        _Memory.Write(_MemoryAddress, (byte)_OpDataOne);
                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = false;
                        break;
                    case OpCodes.LSR_ZX:
                        _InstructionSize = 2;
                        _CycleCount = 4;

                        _MemoryAddress = (ushort)((byte)(_BufferTemp[1] + _RegisterX));
                        _OpDataOne = _Memory.Read(_MemoryAddress);

                        // Set carry if bit 0 is set.
                        CarryFlag = (_OpDataOne & 1) != 0;
                        // Right shift one.
                        _OpDataOne >>= 1;
                        // Write to memory.
                        _Memory.Write(_MemoryAddress, (byte)_OpDataOne);
                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = false;

                        break;
                    #endregion LSR - Shift right one bit (memory or accumulator)

                    #region ROL - Rotate one bit left

                    case OpCodes.ROL_A:
                        _InstructionSize = 3;
                        _CycleCount = 4;

                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]));
                        _OpDataOne = _Memory.Read(_MemoryAddress);

                        //Shift the data over one.
                        _OpDataOne <<= 1;
                        // If carray flag set then set bit zero to 1.
                        _OpDataOne |= (ushort)(CarryFlag ? 0x1 : 0);
                        // Write the value to memory.
                        _Memory.Write(_MemoryAddress, (byte)(0xFF & _OpDataOne));
                        // Set the status flags.
                        CarryFlag = (_OpDataOne & 0x100) != 0;
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) != 0;
                        break;
                    case OpCodes.ROL_ACC:
                        _InstructionSize = 1;
                        _CycleCount = 2;

                        // Set the temp var.
                        _OpDataOne = (ushort)_RegisterAccumulator;

                        //Shift the data over one.
                        _OpDataOne <<= 1;
                        // If carray flag set then set bit zero to 1.
                        _OpDataOne |= (ushort)(CarryFlag ? 0x1 : 0);
                        // Set the accumlator.
                        _RegisterAccumulator = (byte)(0xFF & _OpDataOne);
                        // Set the status flags.
                        CarryFlag = (_OpDataOne & 0x100) != 0;
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) != 0;
                        break;
                    case OpCodes.ROL_AX:
                        _InstructionSize = 3;
                        _CycleCount = 4;

                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterX);
                        _OpDataOne = _Memory.Read(_MemoryAddress);

                        //Shift the data over one.
                        _OpDataOne <<= 1;
                        // If carray flag set then set bit zero to 1.
                        _OpDataOne |= (ushort)(CarryFlag ? 0x1 : 0);
                        // Write the value to memory.
                        _Memory.Write(_MemoryAddress, (byte)(0xFF & _OpDataOne));
                        // Set the status flags.
                        CarryFlag = (_OpDataOne & 0x100) != 0;
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) != 0;
                        break;
                    case OpCodes.ROL_Z:
                        _InstructionSize = 2;
                        _CycleCount = 4;

                        _MemoryAddress = (ushort)(_BufferTemp[1]);
                        _OpDataOne = _Memory.Read(_MemoryAddress);


                        //Shift the data over one.
                        _OpDataOne <<= 1;
                        // If carray flag set then set bit zero to 1.
                        _OpDataOne |= (ushort)(CarryFlag ? 0x1 : 0);
                        // Write the value to memory.
                        _Memory.Write(_MemoryAddress, (byte)(0xFF & _OpDataOne));
                        // Set the status flags.
                        CarryFlag = (_OpDataOne & 0x100) != 0;
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) != 0;
                        break;
                    case OpCodes.ROL_ZX:
                        _InstructionSize = 2;
                        _CycleCount = 4;

                        // Get the address.
                        _MemoryAddress = (ushort)((byte)(_BufferTemp[1] + _RegisterX));
                        //Read from memory.
                        _OpDataOne = _Memory.Read(_MemoryAddress);

                        //Shift the data over one.
                        _OpDataOne <<= 1;
                        // If carray flag set then set bit zero to 1.
                        _OpDataOne |= (ushort)(CarryFlag ? 0x1 : 0);
                        // Write the value to memory.
                        _Memory.Write(_MemoryAddress, (byte)(0xFF & _OpDataOne));
                        // Set the status flags.
                        CarryFlag = (_OpDataOne & 0x100) != 0;
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) != 0;
                        break;

                    #endregion ROL - Rotate one bit left

                    #region ROR - Rotate one bit right

                    case OpCodes.ROR_A:
                        _CycleCount = 2;
                        _InstructionSize = 3;
                        // Get the address.  
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);
                        // Read the byte from memory.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        // Set bit 8 to 1 if carry.
                        _OpDataOne |= (ushort)(CarryFlag ? 0x100 : 0);
                        // Set carry flag if bit one is set.
                        CarryFlag = (_OpDataOne & 0x1) != 0;
                        //Shift the data over one.
                        _OpDataOne >>= 1;
                        // Write the value to memory.
                        _Memory.Write(_MemoryAddress, (byte)(0xFF & _OpDataOne));
                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) != 0;

                        break;


                    case OpCodes.ROR_ACC:
                        _CycleCount = 2;
                        _InstructionSize = 1;
                        _OpDataOne = _RegisterAccumulator;

                        // Set bit 8 to 1 if carry.
                        _OpDataOne |= (ushort)(CarryFlag ? 0x100 : 0);
                        // Set carry flag if bit one is set.
                        CarryFlag = (_OpDataOne & 0x1) != 0;
                        //Shift the data over one.
                        _OpDataOne >>= 1;
                        // Write the value to memory.
                        _RegisterAccumulator = (byte)_OpDataOne;
                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) != 0;
                        break;

                    case OpCodes.ROR_AX:
                        _CycleCount = 2;
                        _InstructionSize = 3;

                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterX);
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        // Set bit 8 to 1 if carry.
                        _OpDataOne |= (ushort)(CarryFlag ? 0x100 : 0);
                        // Set carry flag if bit one is set.
                        CarryFlag = (_OpDataOne & 0x1) != 0;
                        //Shift the data over one.
                        _OpDataOne >>= 1;
                        // Write the value to memory.
                        _Memory.Write(_MemoryAddress, (byte)(0xFF & _OpDataOne));
                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) != 0;
                        break;


                    case OpCodes.ROR_Z:
                        _CycleCount = 2;
                        _InstructionSize = 2;

                        _MemoryAddress = (ushort)(_BufferTemp[1]);
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        // Set bit 8 to 1 if carry.
                        _OpDataOne |= (ushort)(CarryFlag ? 0x100 : 0);
                        // Set carry flag if bit one is set.
                        CarryFlag = (_OpDataOne & 0x1) != 0;
                        //Shift the data over one.
                        _OpDataOne >>= 1;
                        // Write the value to memory.
                        _Memory.Write(_MemoryAddress, (byte)(0xFF & _OpDataOne));
                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) != 0;

                        break;

                    case OpCodes.ROR_ZX:
                        _CycleCount = 2;
                        _InstructionSize = 2;

                        _MemoryAddress = (ushort)((byte)(_BufferTemp[1] + _RegisterX));
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        // Set bit 8 to 1 if carry.
                        _OpDataOne |= (ushort)(CarryFlag ? 0x100 : 0);
                        // Set carry flag if bit one is set.
                        CarryFlag = (_OpDataOne & 0x1) != 0;
                        //Shift the data over one.
                        _OpDataOne >>= 1;
                        // Write the value to memory.
                        _Memory.Write(_MemoryAddress, (byte)(0xFF & _OpDataOne));
                        // Set the status flags.
                        ZeroStatusFlag = _OpDataOne == 0;
                        SignedStatusFlag = (_OpDataOne & _SignedBit) != 0;
                        break;

                    #endregion ROR - Rotate one bit right

                    #endregion Biswise Instructions

                    #region Arithmetic Instructions - Done

                    #region ADC - Add to Accumulator With Carry
                    // Immediate mode.  Add the acculator and the next byte.
                    case OpCodes.ADC:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 2;

                        // Get the value.
                        _OpDataOne = _BufferTemp[1];

                        // Add the value to the accumlator
                        _OpDataTwo = (ushort)(_RegisterAccumulator + _OpDataOne + 
                            (CarryFlag ? _CarryValue : 0));

                        // Set the flags.
                        OverFlowFlag = ((~(_RegisterAccumulator ^ _OpDataOne)) & (_RegisterAccumulator ^ _OpDataTwo) & 0x80) != 0;
                            //!((((_RegisterAccumulator ^ _OpDataOne) & _SignedBit) != 0) && (((_RegisterAccumulator ^ _OpDataTwo) & _SignedBit) != 0));
                        CarryFlag = _OpDataTwo > 0xFF;
                        SignedStatusFlag = (_OpDataTwo & _SignedBit) == _SignedBit;
                        ZeroStatusFlag = (_OpDataTwo & 0xFF) == 0;

                        // Set the accumulator to the value.
                        _RegisterAccumulator = (byte)(0xFF & _OpDataTwo);
                        break;
                    case OpCodes.ADC_Z:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 4;

                        // Get the zero page address.
                        _MemoryAddress = (ushort)(_BufferTemp[1]);
                        // Read the data.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);


                        // Add the value to the accumlator
                        _OpDataTwo = (ushort)(_RegisterAccumulator + _OpDataOne + 
                            (CarryFlag ? _CarryValue : 0));

                        // Set the flags.
                        OverFlowFlag = ((~(_RegisterAccumulator ^ _OpDataOne)) & (_RegisterAccumulator ^ _OpDataTwo) & 0x80)  != 0;
                           // !((((_RegisterAccumulator ^ _OpDataOne) & _SignedBit) != 0) && (((_RegisterAccumulator ^ _OpDataTwo) & _SignedBit) != 0));
                        CarryFlag = _OpDataTwo > 0xFF;
                        SignedStatusFlag = (_OpDataTwo & _SignedBit) != 0;
                        ZeroStatusFlag = (_OpDataTwo & 0xFF) == 0;

                        // Set the accumulator to the value.
                        _RegisterAccumulator = (byte)(0xFF & _OpDataTwo);
                        break;

                    case OpCodes.ADC_ZX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 4;
                        
                        // Get the zero page address.
                        _MemoryAddress = (ushort)((byte)(_BufferTemp[1] + _RegisterX));
                        // Read the data.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);


                        // Add the value to the accumlator
                        _OpDataTwo = (ushort)(_RegisterAccumulator + _OpDataOne + 
                            (CarryFlag ? _CarryValue : 0));

                        // Set the flags.
                        OverFlowFlag = ((~(_RegisterAccumulator ^ _OpDataOne)) & (_RegisterAccumulator ^ _OpDataTwo) & 0x80) != 0;
                            //!((((_RegisterAccumulator ^ _OpDataOne) & _SignedBit) != 0) && (((_RegisterAccumulator ^ _OpDataTwo) & _SignedBit) != 0));
                        CarryFlag = _OpDataTwo > 0xFF;
                        SignedStatusFlag = (_OpDataTwo & _SignedBit) != 0;
                        ZeroStatusFlag = (_OpDataTwo & 0xFF) == 0;

                        // Set the accumulator to the value.
                        _RegisterAccumulator = (byte)(0xFF & _OpDataTwo);
                        break;

                    // Absolute.  The address should be the next 2 bytes 
                    case OpCodes.ADC_A:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;

                        // Get the address.  
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);
                        // Read the byte from memory.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        // Add the value to the accumlator
                        _OpDataTwo = (ushort)(_RegisterAccumulator + _OpDataOne + 
                            (CarryFlag ? _CarryValue : 0));

                        // Set the flags.
                        OverFlowFlag = ((~(_RegisterAccumulator ^ _OpDataOne)) & (_RegisterAccumulator ^ _OpDataTwo) & 0x80) != 0;
                            //!((((_RegisterAccumulator ^ _OpDataOne) & _SignedBit) != 0) && (((_RegisterAccumulator ^ _OpDataTwo) & _SignedBit) != 0));
                        CarryFlag = _OpDataTwo > 0xFF;
                        SignedStatusFlag = (_OpDataTwo & _SignedBit) != 0;
                        ZeroStatusFlag = (_OpDataTwo & 0xFF) == 0;

                        // Set the accumulator to the value.
                        _RegisterAccumulator = (byte)(0xFF & _OpDataTwo);
                        break;

                    case OpCodes.ADC_AX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;

                        // Get the address.  
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterX);
                        // Read the byte from memory.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        // Add the value to the accumlator
                        _OpDataTwo = (ushort)(_RegisterAccumulator + _OpDataOne + 
                            (CarryFlag ? _CarryValue : 0));

                        // Set the flags.
                        OverFlowFlag = ((~(_RegisterAccumulator ^ _OpDataOne)) & (_RegisterAccumulator ^ _OpDataTwo) & 0x80) != 0;
                            //!((((_RegisterAccumulator ^ _OpDataOne) & _SignedBit) != 0) && (((_RegisterAccumulator ^ _OpDataTwo) & _SignedBit) != 0));
                        CarryFlag = _OpDataTwo > 0xFF;
                        SignedStatusFlag = (_OpDataTwo & _SignedBit) != 0;
                        ZeroStatusFlag = (_OpDataTwo & 0xFF) == 0;

                        // Set the accumulator to the value.
                        _RegisterAccumulator = (byte)(0xFF & _OpDataTwo);
                        break;


                    // Absolute.  The address should be the next 2 bytes.  Add y.
                    case OpCodes.ADC_AY:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;

                        // Get the address.  
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterY);
                        // Read the byte from memory.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);


                        // Add the value to the accumlator
                        _OpDataTwo = (ushort)(_RegisterAccumulator + _OpDataOne + 
                            (CarryFlag ? _CarryValue : 0));

                        // Set the flags.
                        OverFlowFlag = ((~(_RegisterAccumulator ^ _OpDataOne)) & (_RegisterAccumulator ^ _OpDataTwo) & 0x80) != 0;
                          //  !((((_RegisterAccumulator ^ _OpDataOne) & _SignedBit) != 0) && (((_RegisterAccumulator ^ _OpDataTwo) & _SignedBit) != 0));
                        CarryFlag = _OpDataTwo > 0xFF;
                        SignedStatusFlag = (_OpDataTwo & _SignedBit) != 0;
                        ZeroStatusFlag = (_OpDataTwo & 0xFF) == 0;

                        // Set the accumulator to the value.
                        _RegisterAccumulator = (byte)(0xFF & _OpDataTwo);
                        break;

                    case OpCodes.ADC_IX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 6;

                        // Read the indirectX address
                        ReadAddressIndirectX();

                        // Read the op data.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        // Add the value to the accumlator
                        _OpDataTwo = (ushort)(_RegisterAccumulator + _OpDataOne +
                            (CarryFlag ? _CarryValue : 0));

                        // Set the flags.
                        OverFlowFlag = ((~(_RegisterAccumulator ^ _OpDataOne)) & (_RegisterAccumulator ^ _OpDataTwo) & 0x80) != 0;
                            //!((((_RegisterAccumulator ^ _OpDataOne) & _SignedBit) != 0) && (((_RegisterAccumulator ^ _OpDataTwo) & _SignedBit) != 0));
                        CarryFlag = _OpDataTwo > 0xFF;
                        SignedStatusFlag = (_OpDataTwo & _SignedBit) != 0;
                        ZeroStatusFlag = (_OpDataTwo & 0xFF) == 0;

                        // Set the accumulator to the value.
                        _RegisterAccumulator = (byte)(0xFF & _OpDataTwo);
                        break;

                    case OpCodes.ADC_IY:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 5;

                        // Get the indirect y address.
                        ReadAddressIndirectY();

                        // Read the op data.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);

                        // Add the value to the accumlator
                        _OpDataTwo = (ushort)(_RegisterAccumulator + _OpDataOne +
                            (CarryFlag ? _CarryValue : 0));

                        // Set the flags.
                        OverFlowFlag = ((~(_RegisterAccumulator ^ _OpDataOne)) & (_RegisterAccumulator ^ _OpDataTwo) & 0x80) != 0;
                            //!((((_RegisterAccumulator ^ _OpDataOne) & _SignedBit) != 0) && (((_RegisterAccumulator ^ _OpDataTwo) & _SignedBit) != 0));
                        CarryFlag = _OpDataTwo > 0xFF;
                        SignedStatusFlag = (_OpDataTwo & _SignedBit) != 0;
                        ZeroStatusFlag = (_OpDataTwo & 0xFF) == 0;

                        // Set the accumulator to the value.
                        _RegisterAccumulator = (byte)(0xFF & _OpDataTwo);
                        break;


                    #endregion ADC

                    #region SBC - Subtract memory from accumulator with borrow
                    // Absolute
                    case OpCodes.SBC:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 2;
                        
                        // Get the value.
                        _OpDataTwo = _BufferTemp[1];

                        // Subtract.
                        _OpDataOne = (ushort)((_RegisterAccumulator - (CarryFlag ? 0 : _CarryValue)) - _OpDataTwo);

                        // Set the flags.
                        OverFlowFlag = ((((_RegisterAccumulator ^ _OpDataTwo) & _SignedBit) != 0) && (((_RegisterAccumulator ^ _OpDataOne) & _SignedBit) != 0));
                        CarryFlag = _OpDataOne < 0x100;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        _RegisterAccumulator = (byte)(0xFF & _OpDataOne);

                        break;
                    case OpCodes.SBC_Z:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 4;
                        // Get the zero page address.
                        _MemoryAddress = (ushort)(_BufferTemp[1]);
                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);

                        // Subtract.
                        _OpDataOne = (ushort)((_RegisterAccumulator - (CarryFlag ? 0 : _CarryValue)) - _OpDataTwo);

                        // Set the flags.
                        OverFlowFlag = ((((_RegisterAccumulator ^ _OpDataTwo) & _SignedBit) != 0) && (((_RegisterAccumulator ^ _OpDataOne) & _SignedBit) != 0));
                        CarryFlag = _OpDataOne < 0x100;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        _RegisterAccumulator = (byte)(0xFF & _OpDataOne);
                        break;

                    case OpCodes.SBC_ZX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 4;
                        // Get the zero page address.
                        _MemoryAddress = (ushort)((byte)(_BufferTemp[1] + _RegisterX));
                        
                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);

                        // Subtract.
                        _OpDataOne = (ushort)((_RegisterAccumulator - (CarryFlag ? 0 : _CarryValue)) - _OpDataTwo);

                        // Set the flags.
                        OverFlowFlag = ((((_RegisterAccumulator ^ _OpDataTwo) & _SignedBit) != 0) && (((_RegisterAccumulator ^ _OpDataOne) & _SignedBit) != 0));
                        CarryFlag = _OpDataOne < 0x100;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        _RegisterAccumulator = (byte)(0xFF & _OpDataOne);
                        break;

                    // Absolute.  The address should be the next 2 bytes 
                    case OpCodes.SBC_A:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the address.  
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);
                        // Read the byte from memory.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);
                        
                        // Subtract.
                        _OpDataOne = (ushort)((_RegisterAccumulator - (CarryFlag ? 0 : _CarryValue)) - _OpDataTwo);

                        // Set the flags.
                        OverFlowFlag = ((((_RegisterAccumulator ^ _OpDataTwo) & _SignedBit) != 0) && (((_RegisterAccumulator ^ _OpDataOne) & _SignedBit) != 0));
                        CarryFlag = _OpDataOne < 0x100;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        _RegisterAccumulator = (byte)(0xFF & _OpDataOne);
                        break;

                    case OpCodes.SBC_AX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the address.  
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterX);
                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);

                        // Subtract.
                        _OpDataOne = (ushort)((_RegisterAccumulator - (CarryFlag ? 0 : _CarryValue)) - _OpDataTwo);

                        // Set the flags.
                        OverFlowFlag = ((((_RegisterAccumulator ^ _OpDataTwo) & _SignedBit) != 0) && (((_RegisterAccumulator ^ _OpDataOne) & _SignedBit) != 0));
                        CarryFlag = _OpDataOne < 0x100;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        _RegisterAccumulator = (byte)(0xFF & _OpDataOne);
                        break;


                    // Absolute.  The address should be the next 2 bytes.  Add y.
                    case OpCodes.SBC_AY:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the address.  
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterY);
                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);

                        // Subtract.
                        _OpDataOne = (ushort)((_RegisterAccumulator - (CarryFlag ? 0 : _CarryValue)) - _OpDataTwo);

                        // Set the flags.
                        OverFlowFlag = ((((_RegisterAccumulator ^ _OpDataTwo) & _SignedBit) != 0) && (((_RegisterAccumulator ^ _OpDataOne) & _SignedBit) != 0));
                        CarryFlag = _OpDataOne < 0x100;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        _RegisterAccumulator = (byte)(0xFF & _OpDataOne);
                        break;

                    case OpCodes.SBC_IX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 6;
                        
                        // Read the indirectX address
                        ReadAddressIndirectX();

                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);

                        // Subtract.
                        _OpDataOne = (ushort)((_RegisterAccumulator - (CarryFlag ? 0 : _CarryValue)) - _OpDataTwo);

                        // Set the flags.
                        OverFlowFlag = ((((_RegisterAccumulator ^ _OpDataTwo) & _SignedBit) != 0) && (((_RegisterAccumulator ^ _OpDataOne) & _SignedBit) != 0));
                        CarryFlag = _OpDataOne < 0x100;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        _RegisterAccumulator = (byte)(0xFF & _OpDataOne);
                        break;

                    case OpCodes.SBC_IY:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 5;
                        
                        // Get the indirect y address.
                        ReadAddressIndirectY();

                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);

                        // Subtract.
                        _OpDataOne = (ushort)((_RegisterAccumulator - (CarryFlag ? 0 : _CarryValue)) - _OpDataTwo);

                        // Set the flags.
                        OverFlowFlag = ((((_RegisterAccumulator ^ _OpDataTwo) & _SignedBit) != 0) && (((_RegisterAccumulator ^ _OpDataOne) & _SignedBit) != 0));
                        CarryFlag = _OpDataOne < 0x100;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        _RegisterAccumulator = (byte)(0xFF & _OpDataOne);
                        break;
                    #endregion SBC - Subtract memory from accumulator with borrow

                    #endregion Arithmetic Instructions

                    #region Compare Instructions - Done

                    #region CMP - Compare memory and accumulator

                    case OpCodes.CMP:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 2;
                        _OpDataOne = (ushort)(_RegisterAccumulator - _BufferTemp[1]);

                        CarryFlag = (_OpDataOne < 0x100) || _OpDataOne == 0;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        break;
                    case OpCodes.CMP_Z:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 4;
                        // Get the zero page address.
                        _MemoryAddress = (ushort)(_BufferTemp[1]);
                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);
                        _OpDataOne = (ushort)(_RegisterAccumulator - _OpDataTwo);
                        // Set the flags
                        CarryFlag = (_OpDataOne < 0x100) || _OpDataOne == 0;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;

                        break;

                    case OpCodes.CMP_ZX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 4;
                        // Get the zero page address.
                        _MemoryAddress = (ushort)((byte)(_BufferTemp[1] + _RegisterX));
                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);
                        _OpDataOne = (ushort)(_RegisterAccumulator - _OpDataTwo);
                        // Set the flags
                        CarryFlag = (_OpDataOne < 0x100);
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        break;

                    // Absolute.  The address should be the next 2 bytes 
                    case OpCodes.CMP_A:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the address.  
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);
                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);
                        _OpDataOne = (ushort)(_RegisterAccumulator - _OpDataTwo);
                        // Set the flags
                        CarryFlag = (_OpDataOne < 0x100) || _OpDataOne == 0;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        break;

                    case OpCodes.CMP_AX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the address.  
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterX);
                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);
                        _OpDataOne = (ushort)(_RegisterAccumulator - _OpDataTwo);
                        // Set the flags
                        CarryFlag = (_OpDataOne < 0x100) || _OpDataOne == 0;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        break;


                    // Absolute.  The address should be the next 2 bytes.  Add y.
                    case OpCodes.CMP_AY:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the address.  
                        _MemoryAddress = (ushort)((_BufferTemp[2] << 8 | _BufferTemp[1]) + _RegisterY);
                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);
                        _OpDataOne = (ushort)(_RegisterAccumulator - _OpDataTwo);
                        // Set the flags
                        CarryFlag = (_OpDataOne < 0x100) || _OpDataOne == 0;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        break;

                    case OpCodes.CMP_IX:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 6;

                        // Read the indirectX address
                        ReadAddressIndirectX();

                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);
                        _OpDataOne = (ushort)(_RegisterAccumulator - _OpDataTwo);
                        // Set the flags
                        CarryFlag = (_OpDataOne < 0x100) || _OpDataOne == 0;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;

                        break;

                    case OpCodes.CMP_IY:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 5;

                        // Get the indirect y address.
                        ReadAddressIndirectY();

                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);
                        _OpDataOne = (ushort)(_RegisterAccumulator - _OpDataTwo);
                        // Set the flags
                        CarryFlag = (_OpDataOne < 0x100) || _OpDataOne == 0;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        break;

                    #endregion CMP - Compare memory and accumulator

                    #region CPX - Compare Memory and Index X
                    case OpCodes.CPX:
                        _InstructionSize = 2;
                        _CycleCount = 2;
                        _OpDataOne = (ushort)(_RegisterX - _BufferTemp[1]);

                        CarryFlag = (_OpDataOne < 0x100) || _OpDataOne == 0;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        break;
                    case OpCodes.CPX_A:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the address.  
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);
                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);
                        _OpDataOne = (ushort)(_RegisterX - _OpDataTwo);
                        // Set the flags
                        CarryFlag = (_OpDataOne < 0x100) || _OpDataOne == 0;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        break;
                    case OpCodes.CPX_Z:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 4;
                        // Get the zero page address.
                        _MemoryAddress = (ushort)(_BufferTemp[1]);
                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);
                        _OpDataOne = (ushort)(_RegisterX - _OpDataTwo);
                        // Set the flags
                        CarryFlag = (_OpDataOne < 0x100) || _OpDataOne == 0;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        break;
                    #endregion CPX - Compare Memory and Index X

                    #region CPY - Compare Memory and Index Y
                    case OpCodes.CPY:
                        _InstructionSize = 2;
                        _CycleCount = 2;
                        _OpDataOne = (ushort)(_RegisterY - _BufferTemp[1]);

                        CarryFlag = (_OpDataOne < 0x100) || _OpDataOne == 0;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        //if (CarryFlag)
                        //{
                        //    TraceLogger.BreakIfAttached();
                        //}
                        break;
                    case OpCodes.CPY_A:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the address.  
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);
                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);
                        _OpDataOne = (ushort)(_RegisterY - _OpDataTwo);
                        // Set the flags
                        CarryFlag = (_OpDataOne < 0x100) || _OpDataOne == 0;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;
                        break;
                    case OpCodes.CPY_Z:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 4;
                        // Get the zero page address.
                        _MemoryAddress = (ushort)(_BufferTemp[1]);
                        // Read the data.
                        _OpDataTwo = (ushort)_Memory.Read(_MemoryAddress);
                        _OpDataOne = (ushort)(_RegisterY - _OpDataTwo);
                        // Set the flags
                        CarryFlag = (_OpDataOne < 0x100) || _OpDataOne == 0;
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        ZeroStatusFlag = (_OpDataOne & 0xFF) == 0;

       
                        break;
                    #endregion CPY - Compare Memory and Index Y

                    #region BIT - Test bits in memory with accumulator
                    case OpCodes.BIT_A:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 3;
                        _CycleCount = 4;
                        // Get the address.  
                        _MemoryAddress = (ushort)(_BufferTemp[2] << 8 | _BufferTemp[1]);
                        // Read the byte from memory.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);
                        // Compare the bits.
                        _OpDataTwo = (ushort)(_RegisterAccumulator & _OpDataOne);
                    
                    
                        //Set the overflow and sign flag.
                        OverFlowFlag = ((_OpDataOne & 0x40) != 0);
                        ZeroStatusFlag = ((_OpDataTwo) == 0);
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        break;

                    // Absolute.  The address should be the next 2 bytes 
                    case OpCodes.BIT_Z:
                        // Set the instruction size and cycle count.
                        _InstructionSize = 2;
                        _CycleCount = 3;
                        // Get the zero page address.
                        _MemoryAddress = (ushort)(_BufferTemp[1]);
                        // Read the byte from memory.
                        _OpDataOne = (ushort)_Memory.Read(_MemoryAddress);
                        //Set the overflow and sign flag.
                        _OpDataTwo = (ushort)(_RegisterAccumulator & _OpDataOne);

                        OverFlowFlag = ((_OpDataOne & 0x40) != 0);
                        ZeroStatusFlag = ((_OpDataTwo) == 0);
                        SignedStatusFlag = ((_OpDataOne & _SignedBit) != 0);
                        break;
                    #endregion BIT


                    #endregion Compare Instructions

                    #region Other

                    #region BRK - Break
                    case OpCodes.BRK:
                        
                        _InstructionSize = 1;
                        _CycleCount = 7;
                        _TotalCycles += _CycleCount;
                        _RegisterProgramCounter+=2;
                        _PendingInterrupt = InterruptType.Break;
                        InterruptsEnabled = true;

                        //// Push the address on to the stack.
                        //PushAddress((ushort)(_RegisterProgramCounter + 1));
                        //// Set the break flag to true.
                        //BreakFlag = true;
                        //// Push the register status on to the stack.
                        //Push((byte)_RegisterStatus);
                        //// Set the interrupt flag.
                        //InterruptsEnabled = true;

                        //if (InterruptsEnabled)
                        //{
                           
                        //}
                        
                        continue;
                     //   break;
                    #endregion BRK - Break

                    #region NOP - No operation
                    case OpCodes.NOP:
                        _InstructionSize = 1;
                        _CycleCount = 2;
                        break;
                    #endregion NOP - No operation

                    #endregion Other

                    #region Default
                    default:

                        TraceLogger.BreakIfAttached();
                        TraceLogger.TraceInformation(TraceSubsystem.Cpu,
                            "Instruction Not Implemented 0x{1:X4}\t\t {0}{3}\t\t 0x{2:X2} ",
                                _OpCode.ToString(),
                                _RegisterProgramCounter,
                                ((int)_OpCode),
                                _OpCode.ToString().Length == 3 ? "   " : string.Empty
                        );
                        throw new Exception("Bad instruction !");
                        #if !DEBUG
                        // Reset the system.  Should use error handler here.
                        throw new Exception("Bad instruction !");
                        //SetInterrupt(InterruptType.Reset);
                        #endif
                        break;
                    #endregion Default

                }
                #endregion Op Code Swith
                
                #if DEBUG && CPU_DEBUG
                LogInstruction(_InstructionSize, _CycleCount);
                #endif

                // Later use strongly typed excep and use exception handler to 
                // show user error message and offer to reset.
                if (_InstructionSize == 0)
                {
                    throw new Exception("Bad instruction !");
                }



                // Add the cycle count.
                _TotalCycles += _CycleCount;
                // Incriment by the instruction size.
                _RegisterProgramCounter += _InstructionSize;
            }

            // Return the number of cycles executed.
            return _TotalCycles;
        }
    }
}
